import { Inject, Injectable } from '@nestjs/common';
import { RedisClientType } from 'redis';
import { ConfigService } from '@nestjs/config';

@Injectable()
export class RedisService {
  constructor(
    @Inject('REDIS_CLIENT') private redisClient: RedisClientType,
    private readonly configService: ConfigService,
  ) {}

  /**
   * 获取值
   * @param key 键
   * @returns
   */
  async get(key: string) {
    let KEY = this.configService.get('REDIS_PRE') + key;
    let value = await this.redisClient.get(KEY);
    try {
      value = JSON.parse(value);
    } catch (error) {}
    return value;
  }

  /**
   * 设置值
   * @param key 键
   * @param value 值
   * @param second 过期时间
   */
  async set(key: string, value: any, second?: number) {
    let KEY = this.configService.get('REDIS_PRE') + key;
    value = JSON.stringify(value);
    return await this.redisClient.set(KEY, value, { EX: second });
  }

  /**
   * 删除值
   * @param key
   */
  async del(key: string | string[]) {
    if (!key || key === '*') return 0;
    if (typeof key === 'string') {
      key = this.configService.get('REDIS_PRE') + key;
    } else {
      key = key.map((k) => this.configService.get('REDIS_PRE') + k);
    }
    return await this.redisClient.del(key);
  }

  /**
   * 根据keys删除值
   */
  async delWidthKeys(key:string) {
    let KEY = this.configService.get('REDIS_PRE') + key + ':*';
    let keys = await this.redisClient.keys(KEY);
    return await this.redisClient.del(keys);
  }

  /**
   * 获取对象keys
   * @param key 正则表达式
   * @returns
   */
  async keys(key: string) {
    let KEY = this.configService.get('REDIS_PRE') + key;
    return await this.redisClient.keys(KEY);
  }

  /**
   * 根据keys获取对应值
   * @param keys
   * @returns
   */
  async mget(keys: string[]) {
    const list = await this.redisClient.mGet(keys);
    return list.map((k) => JSON.parse(k));
  }

  /**
   * 获取Redis信息
   */
  async getInfo() {
    const info = await this.redisClient.info();
    // 按行分割字符串
    const lines = info.split('\r\n');
    const parsedInfo = {};
    // 遍历每一行并分割键值对
    lines.forEach((line) => {
      const [key, value] = line.split(':');
      parsedInfo[key?.trim()] = value?.trim();
    });
    return parsedInfo;
  }

  // 获取缓存key数量
  async getDbSize() {
    return await this.redisClient.dbSize();
  }

  /**
   * 命令统计
   * @returns
   */
  async commandStats() {
    const rawInfo = await this.redisClient.info('commandstats');
    // 按行分割字符串
    const lines = rawInfo.split('\r\n');
    const commandStats = [];
    // 遍历每一行并分割键值对
    lines.forEach((line) => {
      const [key, value] = line.split(':');
      if (key && value) {
        commandStats.push({
          name: key?.trim()?.replaceAll('cmdstat_', ''),
          value: +value?.trim()?.split(',')[0]?.split('=')[1],
        });
      }
    });
    return commandStats;
  }

  /**
   * 清除缓存
   * @returns
   */
  async flushAll() {
    return await this.redisClient.flushAll();
  }

  /**
   * 获取所有的key
   * @returns
   */
  async getAllKey() {
    let keys = [];

    for await (const key of this.redisClient.scanIterator()) {
      keys.push(key);
    }
    return keys;
  }
}
